# yamllint disable rule:comments-indentation
name: PullRequestCI

env:
  # Force the stdout and stderr streams to be unbuffered
  PYTHONUNBUFFERED: 1

on:  # yamllint disable-line rule:truthy
  merge_group:
  pull_request:
    types:
      - synchronize
      - reopened
      - opened
    branches:
      - master

jobs:
  RunConfig:
    runs-on: [self-hosted, style-checker-aarch64]
    outputs:
      data: ${{ steps.runconfig.outputs.CI_DATA }}
    steps:
      - name: DebugInfo
        uses: hmarr/debug-action@a701ed95a46e6f2fb0df25e1a558c16356fae35a
      - name: Check out repository code
        uses: ClickHouse/checkout@v1
        with:
          clear-repository: true # to ensure correct digests
          fetch-depth: 0 # to get version
          filter: tree:0
      - name: Labels check
        if: ${{ github.event_name != 'merge_group' }}
        run: |
          cd "$GITHUB_WORKSPACE/tests/ci"
          python3 run_check.py
      - name: Python unit tests
        run: |
          cd "$GITHUB_WORKSPACE/tests/ci"
          echo "Testing the main ci directory"
          python3 -m unittest discover -s . -p 'test_*.py'
          for dir in *_lambda/; do
            echo "Testing $dir"
            python3 -m unittest discover -s "$dir" -p 'test_*.py'
          done
      - name: PrepareRunConfig
        id: runconfig
        run: |
            python3 "$GITHUB_WORKSPACE/tests/ci/ci.py" --configure --outfile ${{ runner.temp }}/ci_run_data.json

            echo "::group::CI configuration"
            python3 -m json.tool ${{ runner.temp }}/ci_run_data.json
            echo "::endgroup::"

            {
              echo 'CI_DATA<<EOF'
              cat  ${{ runner.temp }}/ci_run_data.json
              echo 'EOF'
            } >> "$GITHUB_OUTPUT"
      - name: Re-create GH statuses for skipped jobs if any
        if: ${{ github.event_name != 'merge_group' }}
        run: |
            python3 "$GITHUB_WORKSPACE/tests/ci/ci.py" --infile ${{ runner.temp }}/ci_run_data.json --update-gh-statuses
  BuildDockers:
    needs: [RunConfig]
    if: ${{ !failure() && !cancelled() && toJson(fromJson(needs.RunConfig.outputs.data).docker_data.missing_multi) != '[]' }}
    uses: ./.github/workflows/reusable_docker.yml
    with:
      data: ${{ needs.RunConfig.outputs.data }}
  StyleCheck:
    needs: [RunConfig, BuildDockers]
    if: ${{ !failure() && !cancelled() && contains(fromJson(needs.RunConfig.outputs.data).jobs_data.jobs_to_do, 'Style check')}}
    uses: ./.github/workflows/reusable_test.yml
    with:
      test_name: Style check
      runner_type: style-checker
      run_command: |
          python3 style_check.py
      data: ${{ needs.RunConfig.outputs.data }}
    secrets:
      secret_envs: |
        ROBOT_CLICKHOUSE_SSH_KEY<<RCSK
        ${{secrets.ROBOT_CLICKHOUSE_SSH_KEY}}
        RCSK
  FastTest:
    needs: [RunConfig, BuildDockers]
    if: ${{ !failure() && !cancelled() && contains(fromJson(needs.RunConfig.outputs.data).jobs_data.jobs_to_do, 'Fast test') }}
    uses: ./.github/workflows/reusable_test.yml
    with:
      test_name: Fast test
      runner_type: builder
      data: ${{ needs.RunConfig.outputs.data }}
      run_command: |
          python3 fast_test_check.py

  ################################# Main statges #################################
  # for main CI chain
  #
  Builds_1:
    needs: [RunConfig, FastTest]
    if: ${{ !failure() && !cancelled() && contains(fromJson(needs.RunConfig.outputs.data).stages_data.stages_to_do, 'Builds_1') }}
    # using callable wf (reusable_stage.yml) allows to group all nested jobs under a tab
    uses: ./.github/workflows/reusable_build_stage.yml
    with:
      stage: Builds_1
      data: ${{ needs.RunConfig.outputs.data }}
  Tests_1:
    needs: [RunConfig, Builds_1]
    if: ${{ !failure() && !cancelled() && contains(fromJson(needs.RunConfig.outputs.data).stages_data.stages_to_do, 'Tests_1') }}
    # using callable wf (reusable_stage.yml) allows to group all nested jobs under a tab
    uses: ./.github/workflows/reusable_test_stage.yml
    with:
      stage: Tests_1
      data: ${{ needs.RunConfig.outputs.data }}
  Builds_2:
    needs: [RunConfig, Builds_1]
    if: ${{ !failure() && !cancelled() && contains(fromJson(needs.RunConfig.outputs.data).stages_data.stages_to_do, 'Builds_2') }}
    # using callable wf (reusable_stage.yml) allows to group all nested jobs under a tab
    uses: ./.github/workflows/reusable_build_stage.yml
    with:
      stage: Builds_2
      data: ${{ needs.RunConfig.outputs.data }}
  Tests_2:
    needs: [RunConfig, Builds_2]
    if: ${{ !failure() && !cancelled() && contains(fromJson(needs.RunConfig.outputs.data).stages_data.stages_to_do, 'Tests_2') }}
    # using callable wf (reusable_stage.yml) allows to group all nested jobs under a tab
    uses: ./.github/workflows/reusable_test_stage.yml
    with:
      stage: Tests_2
      data: ${{ needs.RunConfig.outputs.data }}

  ################################# Reports #################################
  # Reports should by run even if Builds_1/2 fail, so put them separatly in wf (not in Tests_1/2)
  Builds_1_Report:
    # run report check for failed builds to indicate the CI error
    if: ${{ !cancelled() && contains(fromJson(needs.RunConfig.outputs.data).jobs_data.jobs_to_do, 'ClickHouse build check') }}
    needs:
      - RunConfig
      - Builds_1
    uses: ./.github/workflows/reusable_test.yml
    with:
      test_name: ClickHouse build check
      runner_type: style-checker-aarch64
      data: ${{ needs.RunConfig.outputs.data }}
  Builds_2_Report:
    # run report check for failed builds to indicate the CI error
    if: ${{ !cancelled() && contains(fromJson(needs.RunConfig.outputs.data).jobs_data.jobs_to_do, 'ClickHouse special build check') }}
    needs:
      - RunConfig
      - Builds_2
    uses: ./.github/workflows/reusable_test.yml
    with:
      test_name: ClickHouse special build check
      runner_type: style-checker-aarch64
      data: ${{ needs.RunConfig.outputs.data }}

  ################################# Stage Final #################################
  #
  FinishCheck:
    if: ${{ !failure() && !cancelled() }}
    needs: [Tests_1, Tests_2, Builds_1_Report, Builds_2_Report]
    runs-on: [self-hosted, style-checker]
    steps:
      - name: Check out repository code
        uses: ClickHouse/checkout@v1
      - name: Check sync status
        if: ${{ github.event_name == 'merge_group' }}
        run: |
          cd "$GITHUB_WORKSPACE/tests/ci"
          python3 sync_pr.py --status
      - name: Finish label
        run: |
          cd "$GITHUB_WORKSPACE/tests/ci"
          python3 finish_check.py
      - name: Auto merge if approved
        if: ${{ github.event_name != 'merge_group' }}
        run: |
          cd "$GITHUB_WORKSPACE/tests/ci"
          python3 merge_pr.py --check-approved


#############################################################################################
###################################### JEPSEN TESTS #########################################
#############################################################################################
  # This is special test NOT INCLUDED in FinishCheck
  # When it's skipped, all dependent tasks will be skipped too.
  # DO NOT add it there
  Jepsen:
    # we need concurrency as the job uses dedicated instances in the cloud
    concurrency:
      group: jepsen
    if: ${{ !failure() && !cancelled() && contains(fromJson(needs.RunConfig.outputs.data).jobs_data.jobs_to_do, 'ClickHouse Keeper Jepsen') }}
    # jepsen needs binary_release build which is in Builds_2
    needs: [RunConfig, Builds_2]
    uses: ./.github/workflows/reusable_test.yml
    with:
      test_name: ClickHouse Keeper Jepsen
      runner_type: style-checker
      data: ${{ needs.RunConfig.outputs.data }}
